import axios, {
    AxiosInstance,
    AxiosRequestConfig,
    AxiosResponse,
    Canceler,
    InternalAxiosRequestConfig
} from 'axios';

// 用于存储请求的 CancelToken 源
const pendingRequests = new Map<string, Canceler>();

// 创建 Axios 实例
const service: AxiosInstance = axios.create({
    baseURL: process.env.REACT_APP_API_URL, // 请替换为你的 API 基础 URL
    timeout: 5000 // 请求超时时间
});

// 生成请求的唯一标识
function generateRequestKey(config: AxiosRequestConfig): string | null {
    if (!config) {
        return null;
    }
    return [config.method, config.url, JSON.stringify(config.params), JSON.stringify(config.data)].join('&');
}

// 请求拦截器
service.interceptors.request.use(
    function (config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
        if (config) {
            const requestKey = generateRequestKey(config);
            // 如果有相同的请求正在进行，则取消之前的请求
            if (requestKey && pendingRequests.has(requestKey)) {
                const cancel = pendingRequests.get(requestKey)!;
                cancel('取消重复请求');
                pendingRequests.delete(requestKey);
            }
            // 为当前请求设置 CancelToken
            const source = axios.CancelToken.source();
            config.cancelToken = source.token;
            if (requestKey) {
                pendingRequests.set(requestKey, source.cancel);
            }
            // 从本地存储获取 token
            const token = localStorage.getItem('token');
            if (token) {
                // 若存在 token，添加到请求头
                config.headers = config.headers || {};
                config.headers['Authorization'] = `Bearer ${token}`;
            }
        }
        return config;
    },
    function (error: any): Promise<never> {
        // 处理请求错误
        console.error('请求错误:', error);
        return Promise.reject(error);
    }
);

// 响应拦截器
service.interceptors.response.use(
    function (response: AxiosResponse): any {
        if (response.config) {
            const requestKey = generateRequestKey(response.config);
            // 请求完成后，从 pendingRequests 中移除
            if (requestKey) {
                pendingRequests.delete(requestKey);
            }
        }
        // 处理响应数据
        return response.data;
    },
    function (error: any): Promise<any> {
        if (axios.isCancel(error)) {
            console.log('请求被取消:', error.message);
            // 返回一个特殊的结果，表明请求被取消
            return Promise.resolve({ canceled: true });
        } else {
            console.error('响应错误:', error);
            if (error.config) {
                const requestKey = generateRequestKey(error.config);
                // 请求出错后，从 pendingRequests 中移除
                if (requestKey) {
                    pendingRequests.delete(requestKey);
                }
            }
            return Promise.reject(error);
        }
    }
);

// 封装请求方法
const request = {
    get: function (url: string, params?: any, isDownload = false): Promise<any> {
        const config: AxiosRequestConfig = {
            url,
            params,
            responseType: isDownload? 'blob' : 'json' // 如果是下载请求，设置响应类型为 blob
        };
        return service.get(url, config);
    },
    post: function (url: string, data?: any, isDownload = false): Promise<any> {
        const config: AxiosRequestConfig = {
            url,
            data,
            responseType: isDownload? 'blob' : 'json' // 如果是下载请求，设置响应类型为 blob
        };
        return service.post(url, config);
    },
    put: function (url: string, data?: any, isDownload = false): Promise<any> {
        const config: AxiosRequestConfig = {
            url,
            data,
            responseType: isDownload? 'blob' : 'json' // 如果是下载请求，设置响应类型为 blob
        };
        return service.put(url, config);
    },
    delete: function (url: string, params?: any, isDownload = false): Promise<any> {
        const config: AxiosRequestConfig = {
            url,
            params,
            responseType: isDownload? 'blob' : 'json' // 如果是下载请求，设置响应类型为 blob
        };
        return service.delete(url, config);
    }
};

export default request;